﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Text;

using FRL.DebtChased.Extensions;

namespace FRL.DebtChased.Repository.ViewModels
{

	/// <summary>
	/// Declaration of LetterTypesModel class
	/// </summary>
	[Serializable]
	public class LetterTypesModel
	{

		/////////////////////////////////////////////////////////////
		// Nested classes

		[Serializable]
		public class Element
		{

			/////////////////////////////////////////////////////////
			// Attributes

			public int LetterTypeId { get; set; }

			public string Name { get; set; }

			public LetterType.eDays Days { get; set; }
			public string DaysAsText 
			{
				get {
					if ((Days & LetterType.eDays.Immediate) == LetterType.eDays.Immediate)
						return Definitions.Immediate;
					else
						return this.Days.ToString(); 
				}
			}

			public int TimeMinutes { get; set; }
			public string TimeMinutesAsText
			{
				get { return this.TimeMinutes.ToTimeMinutesString(); }
			}

			public int UsageCount { get; set; }
			public string InUseAsText
			{
				get { return this.UsageCount > 0 ? "Yes" : "No"; }
			}

			public string ModifiedAsText { get; set; }

			/////////////////////////////////////////////////////////
			// Construction

			public Element( int iLetterTypeId )
			{

				// Initialize member variables
				this.LetterTypeId = iLetterTypeId;

			}

		}

		/////////////////////////////////////////////////////////////
		// Constants and Enumerations

		/////////////////////////////////////////////////////////////
		// Attributes

		private List<Element> m_elements = new List<Element>();
		public List<Element> Elements
		{
			get { return m_elements; }
		}

		/////////////////////////////////////////////////////////////
		// Construction

		public LetterTypesModel(DebtChasedEntities ent)
		{

			// Load from stored procedure
			var results = ent.LetterTypesProc();

			// Load the element list
			foreach (var ob in results)
			{

				// Add a new element
				Element el = new Element(ob.fdLetterTypeId);
				el.Name = ob.fdName;
				el.TimeMinutes = ob.fdTimeMinutes;
				el.Days = (LetterType.eDays) ob.fdDayFlags;
				el.UsageCount = ob.fdUsageCount;
				if(ob.fdModifiedAt != null)
					el.ModifiedAsText = string.Format("{0} by {1}",
					ob.fdModifiedAt.Value.ToCuteString(),
					ob.fdModifiedBy
				);
				m_elements.Add(el);

			}

		}

		/////////////////////////////////////////////////////////////
		// Operations

		public string Set( DebtChasedEntities ent, int iUserId )
		{

			// Declare return variable
			string strError = null;

			try
			{

				// Get the existing letter-type
				List<LetterType> current = (from lt in ent.LetterTypes select lt).ToList();

				// Update the current items
				foreach (LetterType letterType in current)
				{

					// Find in the model
					LetterTypesModel.Element modelElement = this.FindByLetterTypeId(letterType.LetterTypeId);

					// If model element found...
					if (modelElement != null)
					{

						// Compare details
						if (
							(modelElement.Name != letterType.Name)
							||
							(modelElement.Days != letterType.Days)
							||
							(modelElement.TimeMinutes != letterType.TimeMinutes)
						)
						{

							// Update the letter-type
							letterType.Name = modelElement.Name;
							letterType.Days = modelElement.Days;
							letterType.TimeMinutes = modelElement.TimeMinutes;

						}

					}
					else
					{

						// Alert has been deleted
						ent.LetterTypes.DeleteObject(letterType);

					}

				}

				// Add new alert
				foreach (LetterTypesModel.Element el in this.Elements)
				{

					// If this status has a zero or negative 
					if (el.LetterTypeId <= 0)
					{

						// Add a new status to the database
						LetterType newLetterType = LetterType.CreateLetterType(0, el.Name, (int)el.Days, el.TimeMinutes);
						ent.LetterTypes.AddObject(newLetterType);

					}

				}

				// Save changes to the database
				ent.SaveChanges();

			}
			catch (Exception x)
			{

				// Process exception
				strError = ErrorProcessing.HandleException(x, "save letter type", iUserId);

			}

			// Return variable
			return strError;

		}

		public int GetNextNewId()
		{

			// Declare return variable
			int iFtmp = 0;

			// Find the lowest id
			foreach (Element el in m_elements)
				iFtmp = Math.Min(iFtmp,el.LetterTypeId);
			iFtmp--;

			// Return variable
			return iFtmp;

		}

		public Element FindByName(string strName, Element Ignore)
		{

			// Declare return variable
			Element Ftmp = null;

			// Loop through the elements
			foreach (Element el in m_elements)
			{
				if (el == Ignore)
					continue;
				if (string.Compare(strName,el.Name,true)==0)
				{
					Ftmp = el;
					break;
				}
			}

			// Return variable
			return Ftmp;

		}

		public Element FindByLetterTypeId(int iLetterTypeId)
		{

			// Declare return variable
			Element Ftmp = null;

			// Loop through the elements
			foreach (Element el in m_elements)
			{
				if (el.LetterTypeId == iLetterTypeId)
				{
					Ftmp = el;
					break;
				}
			}

			// Return variable
			return Ftmp;

		}

	}

}
